#======================
# imports
#======================
import os
import re
import sys
sys.path.append(os.path.abspath('.'))
sys.path.append(os.path.abspath('.')+'\\Library\\PLib')
import subprocess
import threading
import time
import tkinter as tk
from datetime import datetime
from json import JSONDecodeError
from tkinter import *
from tkinter import Menu, Spinbox
from tkinter import messagebox as mBox
from tkinter import scrolledtext, ttk
from tkinter.constants import END
import tkinter.font as tf

from croniter import CroniterBadCronError, CroniterNotAlphaError, croniter
from Library.Libs.motd import *

from Library.Libs.Logger import log_error, log_info, log_warn, log_debug
from Library.Libs.src import *
import Library.Libs.Basic as Basic
import Library.Libs.Tool as tool
from Library.Libs.FakePlayer import *



Used = False
NormalStop = False


def edit_ragular(content):
    Basic.Editregular(win,content,True)


#输出控制台
class WriteConsole():
    def write(self,string):
        self.i = 0
        try:
            ft = tf.Font(family='微软雅黑',size=10)
            a = str(self.i+1)+'.0'
            sc.tag_add('tag',END)
            sc.tag_add('tag1',END)
            sc.tag_add('tag2',END)
            sc.tag_add('tag3',END)
            sc.configure(state='normal')
            if 'ERRO' in string:
                sc.tag_config('tag',foreground='#F14C4C',font=ft)
                sc.insert(END,string+'\n','tag')
            elif 'WARN' in string:
                sc.tag_config('tag1',foreground='#F5F543',font=ft)
                sc.insert(END,string+'\n','tag1')
            elif 'INFO' in string:
                sc.tag_config('tag2',foreground='#23D18B',font=ft)
                sc.insert(END,string+'\n','tag2')
            elif 'DEBUG' in string:
                sc.tag_config('tag3',foreground='#11A1C5',font=ft)
                sc.insert(END,string+'\n','tag3')
            sc.configure(state='disabled')
            if config['AutoRecordBot']:
                with open('Temp/BotConsole.txt','a',encoding='utf8') as f:
                    f.write(string)
        except Exception as e:
            #log_debug(e)
            pass

writeconsole = WriteConsole()
#sys.stdout = writeconsole
#===================================================================          
def build_window():
    global win,monty,tab1,tab2,tab3,tab4
    win = tk.Tk()   
    win.title("Phsebot")
    win.resizable(0,0)
    tabControl = ttk.Notebook(win)          
    tab1 = ttk.Frame(tabControl)           
    tabControl.add(tab1, text=PLP['MainUI.BDS'])      
    tab2 = ttk.Frame(tabControl)            
    tabControl.add(tab2, text=PLP['MainUI.regular'])      
    tab3 = ttk.Frame(tabControl)            
    tabControl.add(tab3, text=PLP['MainUI.cron']) 
    tab4 = ttk.Frame(tabControl)           
    tabControl.add(tab4, text=PLP['MainUI.Contrl'])          
    tabControl.pack(expand=1, fill="both")

    monty = ttk.LabelFrame(tab1, text=PLP['BDSUI.frame'],width=500,height=100)
    monty.grid(column=0, row=0, padx=1, pady=10,)
    win.iconbitmap(r'Library/Images/bot.ico')
    win.geometry('725x415')
 
def runcmd():
    global Started
    try:
        global NormalStop
        result=nameEntered.get()+'\r\n'
        cmd = result.encode('utf-8')
        if result.encode('utf-8') == b'stop\r\n':
            NormalStop = True
            Started = False
        obj.stdin.write(result.encode('utf-8'))
        obj.stdin.flush()
        nameEntered.delete(0, 'end')
    except Exception as e:
        log_debug(e)

def Textruncmd(text):
    global Started
    try:
        global NormalStop
        result=text+'\r\n'
        if result.encode('utf-8') == b'stop\r\n':
            NormalStop = True
            Started = False
        obj.stdin.write(result.encode('utf-8'))
        obj.stdin.flush()
    except Exception as e:
        log_debug(e)



def Botruncmd(text:str):
    global NormalStop,Started
    result=text+'\r\n'
    cmd = result
    #开服
    if text == 'start':
        if not check(obj):
            runserver()
        else:
            if Language['ServerRunning'] != False:
                for i in config['Group']:
                    sendGroupMsg(i,Language['ServerRunning'])
                
    #正常关服
    elif text == 'stop':
        NormalStop = True
        DisConnectAllPlayer()
        Started = False
        if check(obj):
            obj.stdin.write(cmd.encode('utf8'))
            obj.stdin.flush()
        else:
            if Language['ServerNotRunning'] != False:
                for i in config['Group']:
                    sendGroupMsg(i,Language['ServerNotRunning'])

    #绑定XboxID
    elif 'bindid' in text:
        if '"' not in text:
            args = text.split(' ')
            qqid = int(args[1])
            group = int(args[-1])
            name = args[2]
            bind(qqid,name,group)
        else:
            args = text.split(' ')
            qqid = int(args[1])
            group = int(args[-1])
            name = re.search(r'\"(.*)\"',text)[0].replace('"','')
            bind(qqid,name,group)

    #解绑XboxID
    elif 'unbind' in text:
        args = text.split(' ')
        qqid = int(args[1])
        group = int(args[-1])
        unbind(qqid,group)

    #发送卡片list
    elif 'cardlist' == text:
        if check(obj):
            Textruncmd('list')
            cl = threading.Thread(target=cardlist)
            cl.setName('CardList')
            cl.start()
        else:
            if Language['ServerNotRunning']:
                for i in config['Group']:
                    sendGroupMsg(i,Language['ServerNotRunning'])

    #Motd请求
    elif 'motd' in text:
        args = text.split(' ')
        addr = ''
        port = ''
        group = int(args[-1])
        args.remove(str(group))
        #匹配域名
        for i in args:
            if re.search(r'(([01]{0,1}\d{0,1}\d|2[0-4]\d|25[0-5])\.){3}([01]{0,1}\d{0,1}\d|2[0-4]\d|25[0-5])',i) or re.search(r'[a-zA-Z0-9][-a-zA-Z0-9]{0,62}(.[a-zA-Z0-9][-a-zA-Z0-9]{0,62})+.?',i):
                addr = i
        #赋值地址
        if ':' in addr:
            d = addr.split(':')
            addr = d[0]
            port = d[1]
        else:
            port = '19132'

        m = threading.Thread(target=tool.motdServer,args=(addr,port,group))
        m.setName('MotdServer')
        m.start()

    #输出名单
    elif 'outlist' == text:
        if check(obj):
            Textruncmd('list')
            cl = threading.Thread(target=outList)
            cl.setName('OutList')
            cl.start()
        else:
            if Language['ServerNotRunning']:
                for i in config['Group']:
                    sendGroupMsg(i,Language['ServerNotRunning'])

    #解析假人命令
    elif 'FakePlayer' in text:
        args = text.split(' ')
        #获取假人名
        if '"' in text:
            name = re.search(r'\"(.*)\"',text)[0].replace('"','')
        else:
            if len(args) > 2:
                name = args[2]
            else:
                name = ''

        #添加假人FakePlayer add Test <Steve> <AllowChat>
        if args[1] == 'add':
            if len(args) >= 5:
                if args[4] == 'true':
                    b = True
                else:
                    b = False
                AddFakePlayer(name,args[3],b)
            
            elif len(args) == 4:
                AddFakePlayer(name,args[3])

            elif len(args) == 3:
                AddFakePlayer(name)
            
            else:
                for i in config['Group']:
                    sendGroupMsg(i,Language['FakePlayerError'].replace(r'%error%',PLP['FakePlayer.ARGError']))
        
        #移除假人FakePlayer remove Test:
        elif args[1] == 'remove':
            if len(args) == 3:
                RemoveFakePlayer(name)
            else:
                for i in config['Group']:
                    sendGroupMsg(i,Language['FakePlayerError'].replace(r'%error%',PLP['FakePlayer.ARGError']))

        #断开连接假人FakePlayer disconnect Test:
        elif args[1] == 'disconnect':
            if len(args) == 3:
                RemoveFakePlayer(name)
            else:
                for i in config['Group']:
                    sendGroupMsg(i,Language['FakePlayerError'].replace(r'%error%',PLP['FakePlayer.ARGError']))

        #连接假人
        elif args[1] == 'connect':
            if len(args) == 3:
                ConnectPlayer(name)
            else:
                for i in config['Group']:
                    sendGroupMsg(i,Language['FakePlayerError'].replace(r'%error%',PLP['FakePlayer.ARGError']))

        #设置聊天
        elif args[1] == 'setchat':
            if len(args) == 4:
                setChatControl(name,args[3])
            elif len(args) == 3:
                setChatControl(name)
            else:
                for i in config['Group']:
                    sendGroupMsg(i,Language['FakePlayerError'].replace(r'%error%',PLP['FakePlayer.ARGError']))

        #获取状态
        elif args[1] == 'getstate':
            if len(args) == 3:
                GetState(name)
            else:
                for i in config['Group']:
                    sendGroupMsg(i,Language['FakePlayerError'].replace(r'%error%',PLP['FakePlayer.ARGError']))

        #获取所有状态
        elif args[1] == 'allstate':
            GetAllState()

        #获取所有假人
        elif args[1] == 'list':
            GetList()

        #移除所有假人
        elif args[1] == 'removeall':
            Remove_All()
    #执行指令
    else:
        def incmd():
            if check(obj):
                obj.stdin.write(cmd.encode('utf8'))
                obj.stdin.flush()
            else:
                if Language['ServerNotRunning']:
                    for i in config['Group']:
                        sendGroupMsg(i,Language['ServerNotRunning'])

        '''if plugin.loader:
            from Library.Plugin import cmds
            if text in cmds:
                cmds[text]()
            else:
                incmd()
        else:'''
        incmd()
        
        

Restart = 0
Players = {
    "Now":0,
    "Max":0,
    "Player":''
}
def checkBDS():
    global StartedServer,Restart
    while True:
        time.sleep(1)
        if not check(obj) and NormalStop == True:
            runserverb.configure(state='normal')
            runserverc.configure(state='normal')
            stoper.configure(state='disabled')
            scr.insert('end','[INFO] %s' % PLP['BDSContorl.Poll.stop'])
            ServerNow.configure(text='%s %s' % (PLP['BDSUI.State'],PLP['Server.NoRunning']))
            GameFile.configure(text=PLP['BDSUI.World'])
            GameVersion.configure(text=PLP['BDSUI.Version'])
            action.configure(state='disabled')
            nameEntered.configure(state='disabled')
            break

        elif not check(obj) and NormalStop == False and config['AutoRestart']:
            if Language['AbendServer'] != False:
                for i in config['Group']:
                    sendGroupMsg(i,Language['AbendServer'])
            if Language['RestartServer'] != False:
                for i in config['Group']:
                    sendGroupMsg(i,Language['RestartServer'])
            ServerNow.configure(text='%s %s' % (PLP['BDSUI.State'],PLP['Server.NoRunning']))
            GameFile.configure(text=PLP['BDSUI.World'])
            GameVersion.configure(text=PLP['BDSUI.Version'])
            if config['MaxAutoRestart'] > Restart:
                runserver()
                Restart += 1
            else:
                for i in config['Group']:
                    sendGroupMsg(i,Language['MaxRestart'])
                Restart = 0
            break

        elif not check(obj) and NormalStop == False and config['AutoRestart'] == False:
            if Language['AbendServer'] != False:
                for i in config['Group']:
                    sendGroupMsg(i,Language['AbendServer'])
            runserverb.configure(state='normal')
            runserverc.configure(state='normal')
            stoper.configure(state='disabled')
            scr.insert('end','[INFO] %s' % PLP['BDSContorl.Poll.stop'])
            ServerNow.configure(text='%s %s' % (PLP['BDSUI.State'],PLP['Server.NoRunning']))
            GameFile.configure(text=PLP['BDSUI.World'])
            GameVersion.configure(text=PLP['BDSUI.Version'])
            action.configure(state='disabled')
            nameEntered.configure(state='disabled')
            break

def insertscr(line):
    global Last,Started    
    try:
        line = line.decode('utf8')
    except UnicodeDecodeError:
        line = line.decode('gbk')
    #删除颜色代码
    colorre = r'\[(.+?)m'
    linec = re.findall(colorre,line)
    for i in linec:
        line = line.replace('\033['+i+'m','')

    #捕捉玩家列表
    pl = re.findall(r'^There\sare(.+?)\/(.+?)\sp',line)
    if pl != []:
        Players['Now'] = int(pl[0][0])
        Players['Max'] = int(pl[0][1])

    #存储上一个
    if re.search(r'^There\sare(.+?)\/(.+?)\sp',Last) != None:
        Players['Player'] = line
        
    Last = line

    #触发自动改名
    if config['AutoChangeBotName']['Enable'] and Started:
        ChangeBotName(Started)
    
    #自定义屏蔽输出
    if config['NoOut']:
        #字符串
        if NoOut['AllLine'] != None:
            for i in NoOut['AllLine']:
                if i in line:
                    line = ''
        
        #替换
        if NoOut['ReplaceLine'] != None:
            for i in NoOut['ReplaceLine']:
                line = line.replace(i,'')

        #正则
        if NoOut['Regular'] != None:
            for i in NoOut['Regular']:
                if re.search(i,line) != None:
                    line = ''

    if line != '':
        scr.configure(state='normal')
        scr.insert('end',line)
        scr.see(END)
        if config['AutoRecordBDS']:
            with open('Temp/BDSConsole.txt','a',encoding='utf8') as f:
                f.write(line[:-2]+'\n')
        scr.configure(state='disabled')

    #使用控制台正则
    try:
        updateLine = line
        back = useconsoleregular(updateLine)
        #玩家退服
        if re.findall(r'^\[INFO\]\sPlayer\sdisconnected:\s(.+?),\sxuid:\s(.+?)$',updateLine) != []:
            r = re.findall(r'^\[INFO\]\sPlayer\sdisconnected:\s(.+?),\sxuid:\s(.+?)$',updateLine)
            if Language['PlayerLeft'] != False:
                for g in config["Group"]:
                    sendGroupMsg(g,Language['PlayerLeft'].replace('%player%',r[0][0]).replace(r'%xuid%',r[0][1]))

        #玩家进服
        if re.findall(r'^\[INFO\]\sPlayer\sconnected:\s(.+?),\sxuid:\s(.+?)$',updateLine) != []:
            r = re.findall(r'^\[INFO\]\sPlayer\sconnected:\s(.+?),\sxuid:\s(.+?)$',updateLine)
            if Language['PlayerJoin'] != False:
                for g in config["Group"]:
                    sendGroupMsg(g,Language['PlayerJoin'].replace('%player%',r[0][0]).replace(r'%xuid%',r[0][1]))

        if back['Type'] == 'Cmd':
            Botruncmd(back['Cmd'])
    except OSError as e:
        log_debug(e)
        

    #内置正则
        #版本
    if 'INFO] Version' in line:
        Version = re.findall(r'Version\s(.+?)[\r\s]',line)[0]
        GameVersion.configure(text=PLP['BDSUI.Version']+Version)
        if Language['ServerVersion'] != False:
            for b in config["Group"]:
                sendGroupMsg(b,Language['ServerVersion'].replace('%Version%',Version))
        #打开世界
    if 'opening' in line:
        World = re.findall(r'opening\s(.+?)[\r\s]',line)[0]
        GameFile.configure(text=PLP['BDSUI.World']+World)
        if Language['OpenWorld'] != False:
            for b in config["Group"]:
                sendGroupMsg(b,Language['OpenWorld'].replace('%World%',World))
        #加载端口
    if 'IPv4' in line:
        Port = int(re.findall(r'^\[INFO\]\sIPv4\ssupported,\sport:\s(.+?)$',line)[0])
        try:
            with open('Temp\\data','w') as f:
                f.write(str(Port))
        except Exception as e:
            log_debug(e)
        if Language['PortOpen'] != False:
            for b in config["Group"]:
                sendGroupMsg(b,Language['PortOpen'].replace('%Port%',str(Port)))

        #开服完成
    if 'Server started' in line:
        if Language['ServerStart'] != False:
            for b in config["Group"]:
                sendGroupMsg(b,Language['ServerStart'])
        #触发假人服务
        ConnectAllPlayer()
        Started = True

        #关服中
    if '[INFO] Server stop requested.' in line:
        if Language['ServerStopping'] != False:
            for b in config["Group"]:
                sendGroupMsg(b,Language['ServerStopping'])
            ChangeBotName(Started)
        

        #关服完成
    if 'Quit correctly' in line:
        if Language['ServerStoped'] != False:
            for b in config["Group"]:
                sendGroupMsg(b,Language['ServerStoped'])

        #崩溃
    if 'Crashed' in line:
        if Language['Crashed'] != False:
            for b in config["Group"]:
                sendGroupMsg(b,Language['Crashed'])

def showinfo():
    global Version,Sended,World,Port,Players,Last,Started
    Started = False
    Last = ''
    for line in iter(obj.stdout.readline, b''):
        insertscr(line)
    for li in iter(obj.stderr.readline, b''):
        insertscr(li)
    obj.stdout.close()
    obj.wait()

def stoperd():
    global NormalStop
    answer = mBox.askyesno(PLP['BDSUI.ForceStop.title'], PLP['BDSUI.ForceStop.message']) 
    if answer == True:
        NormalStop = True
        subprocess.Popen("cmd.exe /k taskkill /F /T /PID %i" % obj.pid,stdout=subprocess.PIPE)  
        if Language['ForcedStop'] != False:
            for i in config['Group']:
                sendGroupMsg(i,Language['ForcedStop'])
        action.configure(state='disabled')
        nameEntered.configure(state='disabled')
        
def runserver():
    global obj,Sended,NormalStop
    NormalStop = False
    Sended = []
    nameEntered.configure(state='normal')
    action.configure(state='normal')
    scr.delete(1.0,'end')
    runserverb.configure(state='disabled')
    runserverc.configure(state='disabled')
    stoper.configure(state='normal')
    ServerNow.configure(text='%s %s' % (PLP['BDSUI.State'],PLP['Server.Running']))

    #新版控制台
    #
    obj = subprocess.Popen('Library\index.bat', stdout=subprocess.PIPE,stderr=subprocess.PIPE,stdin=-1,bufsize=1,shell=True)
    show = threading.Thread(target=showinfo)
    show.setName('ShowBDSConsole')
    show.start()

    c = threading.Thread(target=checkBDS)
    c.setName('CheckBDS')
    c.start()
    if Language['Starting'] != False:
        for i in config['Group']:
            sendGroupMsg(i,Language['Starting'])

def runfileserver():
    global obj
    scr.delete(1.0,'end')
    obj = os.system("start Library\index.bat")
    runserverb.configure(state='disabled')
    runserverc.configure(state='disabled')
    stoper.configure(state='normal')
    ServerNow.configure(text='%s %s' % (PLP['BDSUI.State'],PLP['Server.Running']))
    c = threading.Thread(target=checkBDS)
    c.setName('CheckBDS')
    c.start()

def create_content():
    global runserverb,runserverc,stoper,ServerNow,scr,nameEntered,action,GameFile,GameVersion,ServerUse,infos,mlb,mlc,sc,\
        CpuC
    #BDS控制台日志输出 
    scrolW  = 75; scrolH  =  23.1
    scr = scrolledtext.ScrolledText(monty, width=scrolW, height=scrolH, wrap=tk.WORD)
    scr.grid(column=0, row=0,columnspan=3)
    scr.configure(state='disabled')
    #命令输入
    ttk.Label(monty, text=PLP['BDSUI.InputCommand']).grid(column=0, row=2, sticky='W')
    name = tk.StringVar()
    nameEntered = ttk.Entry(monty, width=70, textvariable=name)
    nameEntered.grid(column=0, row=2, sticky='W')
    

    #执行命令
    action = ttk.Button(monty,text=PLP['BDSUI.run'],width=5,command=runcmd)   
    action.grid(column=1,row=2,rowspan=2)
    action.configure(state='disabled')
    nameEntered.configure(state='disabled')

    tool.createToolTip(action,PLP['BDSUI.Runcommand'])

    tool.createToolTip(scr,PLP['BDSUI.log'])
    tool.createToolTip(nameEntered,PLP['BDSUI.Input'])

    infos = ttk.LabelFrame(tab1, text=PLP['BDSUI.ShowInfo.frame'])
    infos.grid(column=1, row=0, padx=1, pady=10,)

    #QQ信息
    QQInfo = ttk.LabelFrame(infos, text=PLP['BDSUI.ShowInfo.BotInfo'])
    QQid = ttk.Label(QQInfo, text=PLP['BDSUI.ShowInfo.account'],width=20)
    QQid.grid(column=0, row=0,sticky='W')
    version = ttk.Label(QQInfo, text=PLP['BDSUI.ShowInfo.Version']+str(BotVersion),width=20).grid(column=0, row=2,sticky='W')
    QQInfo.grid(column=0, row=0, padx=5, pady=10,sticky='W')
    QQid.configure(text='%s %i' % (PLP['BDSUI.ShowInfo.account'],config['Bot']))

    #服务器信息
    Serverinfos = ttk.LabelFrame(infos, text=PLP['BDSUI.ShowInfo.Server.frame'])
    ServerNow = ttk.Label(Serverinfos, text='%s %s' % (PLP['BDSUI.State'],PLP['Server.NoRunning']),width=20)
    ServerNow.grid(column=0, row=3)
    ttk.Label(Serverinfos, text="=====================",width=20).grid(column=0, row=4)
    GameVersion = ttk.Label(Serverinfos, text=PLP['BDSUI.Version'],width=20)
    GameVersion.grid(column=0, row=5)
    GameFile = ttk.Label(Serverinfos, text=PLP['BDSUI.World'],width=20)
    GameFile.grid(column=0, row=6)
    CpuC = ttk.Label(Serverinfos, text=PLP['MainUI.CPU']+' '+str(cpup)+'%',width=20)
    CpuC.grid(column=0, row=7)
    Serverinfos.grid(column=0, row=1, padx=5, pady=10,sticky='W')

    #服务器操作
    ServerUse = ttk.LabelFrame(infos, text=PLP['BDSUI.ShowInfo.Action.frame'],width=500,height=100)
    runserverb = ttk.Button(ServerUse,text=">",width=2,command=runserver)   
    runserverb.grid(column=0,row=5)
    ttk.Label(ServerUse, text=PLP['BDSUI.ShowInfo.Action.config'],width=17).grid(column=1, row=5)

    runserverc = ttk.Button(ServerUse,text=">",width=2,command=runfileserver)   
    runserverc.grid(column=0,row=6)
    ttk.Label(ServerUse, text=PLP['BDSUI.ShowInfo.Action.file'],width=17).grid(column=1, row=6)

    stoper = ttk.Button(ServerUse,text=">",width=2,command=stoperd)   
    stoper.grid(column=0,row=7)
    ttk.Label(ServerUse, text=PLP['BDSUI.ShowInfo.Action.stop'],width=17,foreground='red').grid(column=1, row=7)
    stoper.configure(state='disabled')

    reload = ttk.Button(ServerUse,text=">",width=2,command=tool.filereload)   
    reload.grid(column=0,row=8)
    ttk.Label(ServerUse, text=PLP['BDSUI.ShowInfo.Action.reload'],width=17).grid(column=1, row=8)

    ServerUse.grid(column=0, row=2, padx=5, pady=10,sticky='W')
    # 一次性控制各控件之间的距离
    for child in infos.winfo_children(): 
        child.grid_configure(padx=3,pady=1)
    #---------------Tab1控件介绍------------------#
 
    lbv=tk.StringVar()#绑定变量
    #---------------Tab2控件介绍------------------#
    def new_regular():
        Basic.Editregular(win,['','','','控制台'],False)
    
    def delete_regular():
        global csd
        from Library.Libs.Tool import csd
        if csd != []:
            #删除正则
            if len(csd) == 4:
                conn = sq.connect('data/regular.db')
                c = conn.cursor()
                c.execute("DELETE from interactive where 正则='%s';" % csd[0])
                conn.commit()
                mBox.showinfo(PLP['RemoveRegular.Ask.title'],'%s\n%s' % (PLP['RemoveRegular.Ask.message'],csd[0]))
                update()
                csd = []
        else:
            mBox.showwarning(PLP['RemoveRegular.Warning.title'],PLP['RemoveRegular.Warning.message'])
    monty2 = ttk.LabelFrame(tab2, text=PLP['ShowRegular.frame'])
    monty2.grid(column=0, row=0, padx=8, pady=4)


    mlb = tool.MultiListbox(monty2,((PLP['ShowRegular.List.regular'], 57),(PLP['ShowRegular.List.run'], 20),(PLP['ShowRegular.List.perm'], 10),(PLP['ShowRegular.List.catch'],10)))
    conn = sq.connect('data/regular.db')
    c = conn.cursor()
    cursor = c.execute("SELECT *  from interactive")
    cmd = ''
    for row in cursor:
        r = row[0]
        by = row[1]
        perm = row[2]
        cmd = row[3]
        mlb.insert(END,(r,cmd,perm,by))
    conn.close()
    mlb.pack(expand=YES, fill=BOTH)

    newregular = tk.Button(monty2,text=PLP['ShowRegular.new'],width=10,command=new_regular)
    newregular.pack(side=LEFT)

    deleter = tk.Button(monty2,text=PLP['ShowRegular.remove'],width=10,command=delete_regular)
    deleter.pack(side=LEFT,padx=3)

    #---------------Tab2控件介绍------------------#
    

    #---------------Tab3控件介绍------------------#
    monty3 = ttk.LabelFrame(tab3, text=PLP['ShowCron.frame'])
    monty3.grid(column=0, row=0, padx=8, pady=4)
    mlc = tool.MultiListbox(monty3,((PLP['ShowCron.List.cron'], 50),(PLP['ShowCron.List.run'], 47)))
    with open('data/Cron.json','r',encoding='utf-8') as f:
        cronl = json.loads(f.read())
    for i in cronl:
        mlc.insert(END,(i['cron'],i['cmd']))
    mlc.pack(expand=YES, fill=BOTH)
    #---------------Tab3控件介绍------------------#

    #---------------Tab4控件介绍------------------#

    scolW  = 99; scolH  =  28
    sc = scrolledtext.ScrolledText(tab4, width=scolW, height=scolH, wrap=tk.WORD)
    sc.grid(column=0, row=0,columnspan=3)
    sc.configure(state='disabled')
    #---------------Tab4控件介绍------------------#
 
 
    #----------------菜单栏介绍-------------------#    
    # Creating a Menu Bar
    menuBar = Menu(win)
    win.config(menu=menuBar)
 
    # Add menu items
    def configw():
        pw = PopupDialog(win)
        win.wait_window(pw)

    fileMenu = Menu(menuBar, tearoff=0)
    fileMenu.add_command(label=PLP['Menu.config'],command=configw)
    fileMenu.add_separator()
    fileMenu.add_command(label=PLP['Menu.exit'], command=on_closing)
    menuBar.add_cascade(label=PLP['Menu.title'], menu=fileMenu)
 
#----------------菜单栏介绍-------------------#

#更新预览
def update():
    global config,Language,cron
    conn = sq.connect('data/regular.db')
    c = conn.cursor()
    cursor = c.execute("SELECT *  from interactive")
    cmd = ''
    mlb.delete(0,END)
    for row in cursor:
        r = row[0]
        by = row[1]
        perm = row[2]
        cmd = row[3]
        mlb.insert(END,(r,cmd,perm,by))
    conn.close()




def on_closing():
    if mBox.askyesno(PLP['Exit.title'],PLP['Exit.message']):
        log_info(PLP['Exit.runExit'])
        log_info(PLP['Exit.release'])
        os._exit(0)
def updatew():
    while True:
        time.sleep(2)
        from Library.Libs.src import cpup
        try:
            CpuC.configure(text=PLP['MainUI.CPU']+' '+str(cpup)+'%')
        except:
            pass

def usegroupregular():
    global sessionKey,ws
    url2 = config["BotURL"]
    while True:
        time.sleep(0.005)
        rt = {}
        regular = {'Console':[],'Group':[],'Msg':[]}
        conn = sq.connect('data/regular.db')
        c = conn.cursor()
        cursor = c.execute("SELECT *  from interactive")
        cmd = ''

        for row in cursor:
            r = row[0]
            by = row[1]
            perm = row[2]
            cmd = row[3]
            if perm == '管理员':
                perm = True
            else:
                perm = False
            if by == '群消息':
                regular['Group'].append({'regular':r,'perm':perm,'run':cmd})
        conn.close()
        try:
            j = json.loads(ws.recv())
        except ConnectionResetError as e:
            log_debug(e)
            mBox.showerror(PLP['Mirai.title'],PLP['Mirai.close'])
            break
        except Exception as e:
            log_debug(e)
            mBox.showerror(PLP['Mirai.title'],PLP['Mirai.insideError'])
            break
        if 'data' in j and 'type' in j['data'] and j['syncId'] != '123':
            if j['data']['type'] == "GroupMessage":
                group = j['data']["sender"]['group']['id']
                senderqq = j['data']['sender']["id"]
                sendername = j['data']['sender']["memberName"]
                Sourceid = 0
                msg = ''
                if len(j['data']["messageChain"]) == 1:
                    for i in j['data']["messageChain"]:
                        if i['type'] == 'Plain':
                            msg = i["text"]
                        elif i['type'] == 'Source':
                            Sourceid = i['id']
                else:
                    msg = ''
                    for i in j['data']["messageChain"]:
                        if i['type'] == 'Plain':
                            msg += i["text"]
                        elif i['type'] == 'At':
                            msg += str(i['target'])
                        elif i['type'] == 'Source':
                            Sourceid = i['id']
                #验证是否是管理的群
                if group in config['Group']:
                    #验证正则
                    for b in regular['Group']:
                        p = re.findall(b['regular'],msg)
                        if p != []:
                            if type(p[0]) == tuple:
                                if len(p[0]) == 1:
                                    cmd = b['run'].replace('$1',p[0][0])
                                elif len(p[0]) == 2:
                                    cmd = b['run'].replace('$1',p[0][0]).replace('$2',p[0][1])
                                elif len(p[0]) == 3:
                                    cmd = b['run'].replace('$1',p[0][0]).replace('$2',p[0][1]).replace('$3',p[0][2])
                                elif len(p[0]) == 4:
                                    cmd = b['run'].replace('$1',p[0][0]).replace('$2',p[0][1]).replace('$3',p[0][2]).replace('$4',p[0][3])
                                elif len(p[0]) == 5:
                                    cmd = b['run'].replace('$1',p[0][0]).replace('$2',p[0][1]).replace('$3',p[0][2]).replace('$4',p[0][3]).replace('$5',p[0][4])
                                elif len(p[0]) == 6:
                                    cmd = b['run'].replace('$1',p[0][0]).replace('$2',p[0][1]).replace('$3',p[0][2]).replace('$4',p[0][3]).replace('$5',p[0][4]).replace('$6',p[0][5])
                                elif len(p[0]) == 7:
                                    cmd = b['run'].replace('$1',p[0][0]).replace('$2',p[0][1]).replace('$3',p[0][2]).replace('$4',p[0][3]).replace('$5',p[0][4]).replace('$6',p[0][5]).replace('$7',p[0][6])
                                elif len(p[0]) == 8:
                                    cmd = b['run'].replace('$1',p[0][0]).replace('$2',p[0][1]).replace('$3',p[0][2]).replace('$4',p[0][3]).replace('$5',p[0][4]).replace('$6',p[0][5]).replace('$7',p[0][6]).replace('$8',p[0][7])
                                elif len(p[0]) == 9:
                                    cmd = b['run'].replace('$1',p[0][0]).replace('$2',p[0][1]).replace('$3',p[0][2]).replace('$4',p[0][3]).replace('$5',p[0][4]).replace('$6',p[0][5]).replace('$7',p[0][6]).replace('$8',p[0][7]).replace('$9',p[0][8])
                            elif type(p[0]) == str:
                                cmd = b['run'].replace('$1',p[0])
                            #发群消息
                            rps = replacegroup(cmd[2:],sendername,senderqq)
                            if b['perm'] == True:
                                if senderqq in config['Admin']:
                                    if b['run'][:2] == '>>':
                                        for g in config["Group"]:
                                            sendGroupMsg(g,rps)
                                    #执行命令
                                    elif b['run'][:2] == '<<':
                                        if 'motd' in cmd[2:]:
                                            Botruncmd(rps+' '+str(group))
                                        elif 'bindid' in cmd[2:]:
                                            Botruncmd(rps+' '+str(group))
                                        elif 'unbind' in cmd[2:]:
                                            Botruncmd(rps+' '+str(group))
                                        elif plugin.checkcmd(rps):
                                            plugin.pluginCmd(rps,group,senderqq,sendername)
                                        else:
                                            Botruncmd(rps)
                                else:
                                    if Language['NoPermission'] != False:
                                        sendGroupMsg(group,Language['NoPermission'])

                            else:
                                if b['run'][:2] == '>>':
                                    for g in config["Group"]:
                                        sendGroupMsg(g,rps)
                                #执行命令
                                elif b['run'][:2] == '<<':
                                    if 'motd' in cmd[2:]:
                                        Botruncmd(rps+' '+str(group))
                                    elif 'bind' in cmd[2:]:
                                        Botruncmd(rps+' '+str(group))
                                    elif 'unbind' in cmd[2:]:
                                        Botruncmd(rps+' '+str(group))
                                    elif plugin.checkcmd(rps):
                                        plugin.pluginCmd(rps,group,senderqq,sendername)
                                    else:
                                        Botruncmd(rps)
                        else:
                            rt = {'Type':'None'}
                    
                    #绑定xboxid
                    if config['AtNoXboxid']['Enable']:
                        qlist = []
                        conn = sq.connect('data/xuid.db')
                        c = conn.cursor()
                        cursor = c.execute("SELECT *  from xboxid")
                        for row in cursor:
                            qq = row[0]
                            qlist.append(qq)
                        conn.close()
                        if senderqq not in qlist:
                            #撤回消息
                            if config['AtNoXboxid']['Recall']:
                                recallmsg(ws,Sourceid)
                            send_at(ws,group,senderqq,Language['AtNotXboxid'])
            #检测改名
            elif j['data']['type'] == "MemberCardChangeEvent":
                qqid = j['data']['member']['id']
                group = j['data']['member']['group']['id']
                qxlist = []
                qlist = []
                xlist = []
                conn = sq.connect('data/xuid.db')
                c = conn.cursor()
                cursor = c.execute("SELECT *  from xboxid")
                for row in cursor:
                    qq = row[0]
                    xboxid = row[1]
                    qxlist.append({'qq':qq,'id':xboxid})
                    qlist.append(qq)
                    xlist.append(xboxid)
                conn.close()
                #检测是否是管理的群
                if group in config['Group']:
                    #检测是否绑定白名单
                    if qqid in qlist and qqid not in config['CheckNick']['WhiteList']:
                        for p in qxlist:
                            if p['qq'] == qqid:
                                if j['data']['current'] != p['id']:
                                    changeName(ws,qqid,group,p['id'])
                                    if Language['ChangeNick'] != False:
                                        send_at(ws,group,qqid,Language['ChangeNick'])

            #检测成员离开群聊
            elif 'MemberLeaveEventKick' == j['data']['type'] or "MemberLeaveEventQuit" == j['data']['type']:
                memberid = j['data']['member']['id']
                group = j['data']['member']['group']['id']
                #验证管理群号
                if group in config['Group'] and config['LeftRemove']:
                    qxlist = []
                    qlist = []
                    xlist = []
                    conn = sq.connect('data/xuid.db')
                    c = conn.cursor()
                    cursor = c.execute("SELECT *  from xboxid")
                    for row in cursor:
                        qq = row[0]
                        xboxid = row[1]
                        qxlist.append({'qq':qq,'id':xboxid})
                        qlist.append(qq)
                        xlist.append(xboxid)
                    conn.close()
                    if memberid in qlist:
                        wl = read_file(config['ServerPath']+'\\whitelist.json')
                        wlrun = False
                        xboxid = r'%xboxid%'
                        for x in qxlist:
                            if x['qq'] == memberid:
                                xboxid = x['id']
                        for names in wl:
                            if names['name'] == xboxid:
                                wlrun = True
                        if wlrun:
                            if Language['LeftGroup'] != False:
                                sendGroupMsg(group,Language['LeftGroup'].replace(r'%xboxid%',xboxid))
                            Botruncmd('whitelist remove "%s"' % xboxid)
        elif j['syncId'] == '123' and 'data' in j:
            try:
                ij = j['data']
                if ij['code'] == 0 and ij['messageId'] == -1:
                    log_warn(PLP['Mirai.send.shield'])
            except JSONDecodeError as e:
                log_debug(e)
                log_error(PLP['Mirai.send.insideError'])

        elif j['syncId'] == '1234' and 'data' in j:
            try:
                ij = j['data']
                if ij['code'] == 10:
                    log_warn(PLP['Mirai.change.NoPermissions'])
            except JSONDecodeError as e:
                log_debug(e)
                log_error(PLP['Mirai.change.insideError'])
            
        elif j['syncId'] == '12345' and 'data' in j:
            try:
                ij = j['data']
                if ij['messageId'] == -1:
                    log_warn(PLP['Mirai.card.shield'])
            except JSONDecodeError as e:
                log_debug(e)
                log_error(PLP['Mirai.card.insideError'])

def useconsoleregular(text):
    rt = {}
    regular = {'Console':[],'Group':[],'Msg':[]}
    conn = sq.connect('data/regular.db')
    c = conn.cursor()
    cursor = c.execute("SELECT *  from interactive")
    cmd = ''
    for row in cursor:
        r = row[0]
        by = row[1]
        perm = row[2]
        cmd = row[3]
        if perm == '管理员':
            perm = True
        else:
            perm = False
        if by == '控制台':
            regular['Console'].append({'regular':r,'perm':perm,'run':cmd})
    conn.close()

    for i in regular['Console']:
        p = re.findall(i['regular'],text)
        #执行操作
        if p != []:
            if type(p[0]) == tuple:
                if len(p[0]) == 1:
                    cmd = i['run'].replace('$1',p[0][0])
                elif len(p[0]) == 2:
                    cmd = i['run'].replace('$1',p[0][0]).replace('$2',p[0][1])
                elif len(p[0]) == 3:
                    cmd = i['run'].replace('$1',p[0][0]).replace('$2',p[0][1]).replace('$3',p[0][2])
                elif len(p[0]) == 4:
                    cmd = i['run'].replace('$1',p[0][0]).replace('$2',p[0][1]).replace('$3',p[0][2]).replace('$4',p[0][3])
                elif len(p[0]) == 5:
                    cmd = i['run'].replace('$1',p[0][0]).replace('$2',p[0][1]).replace('$3',p[0][2]).replace('$4',p[0][3]).replace('$5',p[0][4])
                elif len(p[0]) == 6:
                    cmd = i['run'].replace('$1',p[0][0]).replace('$2',p[0][1]).replace('$3',p[0][2]).replace('$4',p[0][3]).replace('$5',p[0][4]).replace('$6',p[0][5])
                elif len(p[0]) == 7:
                    cmd = i['run'].replace('$1',p[0][0]).replace('$2',p[0][1]).replace('$3',p[0][2]).replace('$4',p[0][3]).replace('$5',p[0][4]).replace('$6',p[0][5]).replace('$7',p[0][6])
                elif len(p[0]) == 8:
                    cmd = i['run'].replace('$1',p[0][0]).replace('$2',p[0][1]).replace('$3',p[0][2]).replace('$4',p[0][3]).replace('$5',p[0][4]).replace('$6',p[0][5]).replace('$7',p[0][6]).replace('$8',p[0][7])
                elif len(p[0]) == 9:
                    cmd = i['run'].replace('$1',p[0][0]).replace('$2',p[0][1]).replace('$3',p[0][2]).replace('$4',p[0][3]).replace('$5',p[0][4]).replace('$6',p[0][5]).replace('$7',p[0][6]).replace('$8',p[0][7]).replace('$9',p[0][8])
            elif type(p[0]) == str:
                cmd = i['run']
            #发群消息
            rps = replaceconsole(cmd[2:])
            if i['run'][:2] == '>>':
                for g in config["Group"]:
                    sendGroupMsg(g,rps)
                rt = {'Type':'Sended'}
            #执行命令
            elif i['run'][:2] == '<<':
                rt = {'Type':'Cmd','Cmd':rps}
        else:
            rt = {'Type':'None'}
    return rt

#输出list名单
def outList():
    time.sleep(1)
    if Language['OnlineList'] != False:
        l = Language['OnlineList'].replace(r'%Online%',str(Players['Now'])).replace(r'%Max%',str(Players['Max'])).replace(r'%Player%',Players['Player'])
        for i in config['Group']:
            sendGroupMsg(i,l)

def cardlist():
    time.sleep(1)
    if config['ServerInfoCard']['Enable']:
        card = config['ServerInfoCard']['CardJson']
        #改变
        card = card.replace('%Online%',str(Players['Now']))
        card = card.replace('%Max%',str(Players["Max"]))
        card = card.replace('%Players%',Players['Player'])
        #替换logo
        if config['ServerInfoCard']['Logo'] != '':
            card = card.replace(r'%Logo%','https:\/\/z3.ax1x.com\/2021\/09\/09\/hOPbZQ.png')
        else:
            card = card.replace(r'%Logo%',config['ServerInfoCard']['Logo'])
        for i in config['Group']:
            send_app(ws,i,card)


#Plugin类
class Plugin():
    def __init__(self) -> None:
        #检测头
        self.loader = False

    def checkcmd(self,cmd:str):
        #检查命令
        if self.loader:
            from Library.Libs.Plugin import cmds
            if cmd.split(' ')[0] in cmds:
                return True
            else:
                return False
        else:
            return False

    def pluginCmd(self,cmd:str,g,i,n):
        from Library.Libs.Plugin import cmds
        class Args():
            def __init__(self,group:int,sender:int,name:str,args = None) -> None:
                self.group = group
                self.senderId = sender
                self.senderName = name
                self.args = args

        if cmds[cmd.split(' ')[0]].type == 'ordinary':
            args = Args(g,i,n)
            cmds[cmd].function(args)
        elif cmds[cmd.split(' ')[0]].type == 'args':
            cmdarg = cmd.split(' ')
            log_debug(cmdarg)
            args = Args(g,i,n,cmdarg)


plugin = Plugin()
class Obj():
    def __init__(self,shell) -> None:
        pass
    def poll(self):
        return 1
obj = Obj(shell=True)
#生成计划任务
if __name__ == '__main__':
    os.system('title Phsebot-V'+str(BotVersion))
    build_window()
    create_content()
    log_info(PLP['Start.starttime']+str(datetime.now()))
    #全局变量
    
    #连接Mirai
    if login():
        from Library.Libs.src import ws
    else:
        mBox.showerror(PLP['Start.Connect.Faild.title'],PLP['Start.Connect.Faild.message'])
        

    #假人服务
    if config['FakePlayerService']['Enable']:
        if Build_Connect():
            log_info(PLP['Start.FakePlayer.Connected'])
        else:
            log_error(PLP['Start.FakePlayer.Failed'])

    #输出废话
    log_info('Phsebot was successfully started')
    log_info('Author: HuoHuaX')
    log_info('Special Thanks McPlus Yanhy2000 strong support for this project')

    #杂项
    tool.writeconfig()
    tool.crontab()
    
    #启用线程
    upd = threading.Thread(target=updatew)
    upd.setDaemon(True)
    upd.setName('UpWindow')
    upd.start()

    updv = threading.Thread(target=testupdate)
    updv.setDaemon(True)
    updv.setName('UpDateBot')
    updv.start()
    if config['EnableCron']:
        croncmdt = threading.Thread(target=tool.runcron)
        croncmdt.setName('Cron_Timer')
        croncmdt.start()

    if config['EnableGroup']:
        gmsp = threading.Thread(target=usegroupregular)
        gmsp.setName('RecvGroupMsg')
        gmsp.start()

    win.protocol("WM_DELETE_WINDOW", on_closing)
    
    #导入加载器
    try:
        from Library.Libs.Plugin import Author
        from Library.Libs.Plugin import Type
    except ImportError:
        pass
    else:
        #完成全部导入
        from Library.Libs.Plugin import *
        log_info(PLP['Plugin.load'].replace(r'%TYPE%',Type).replace(r'%AUTHOR%',Author))

        plugin.loader = True

    try:
        win.mainloop()
    except KeyboardInterrupt as e:
        log_debug(e)
        on_closing()
    

